task automatic send_pck(
	input [X_NODE_NUM_WIDTH-1		:	0] src_x_addr,
	input [Y_NODE_NUM_WIDTH-1		:	0] src_y_addr,
	input [X_NODE_NUM_WIDTH-1		:	0] des_x_addr,
	input [Y_NODE_NUM_WIDTH-1		:	0] des_y_addr,
	input [`NIC_PCK_SIZE_WIDTH-1	:	0]	pck_size,
	input [`NIC_PTR_WIDTH-1			:	0]	pck_ptr


);
	begin: send_pck1
		write_hdr ( src_x_addr,src_y_addr,des_x_addr,des_y_addr,pck_ptr);
		#20
		send_pck_cmd (src_x_addr, src_y_addr,	pck_size,pck_ptr);
		wait(	nic_s_readdata[`CORE_NUM(src_x_addr,src_y_addr)][`NIC_WR_DONE_LOC] );
	end
endtask


//////////////////////////////////



task automatic send_pck_cmd (
	input [X_NODE_NUM_WIDTH-1	:	0] src_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] src_y_addr,
	input [12						:	0]	pck_size,
	input [18						:	0]	pck_ptr
	
);

	begin : send_pck_cmd1
		nic_s_address		[`CORE_NUM(src_x_addr,src_y_addr)] 						= SLAVE_WR_PCK_ADDR; 
		nic_s_writedata	[`CORE_NUM(src_x_addr,src_y_addr)]						= {pck_size,pck_ptr}; 
		nic_s_chipselect	[`CORE_NUM(src_x_addr,src_y_addr)]						=	1'b1;
		@ (posedge clk) # 1	nic_s_write[`CORE_NUM(src_x_addr,src_y_addr)]	=	1'b1;
		@ (posedge clk) # 1	nic_s_write[`CORE_NUM(src_x_addr,src_y_addr)]	=	1'b0;
		nic_s_writedata	[`CORE_NUM(src_x_addr,src_y_addr)]						=	0;
	end
endtask

////////////////////////////////////

task automatic write_hdr (
	input [X_NODE_NUM_WIDTH-1	:	0] src_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] src_y_addr,
	input [X_NODE_NUM_WIDTH-1	:	0] des_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] des_y_addr,
	input [`NIC_PTR_WIDTH-1		:	0]	pck_ptr


);
	begin : hdr1
	nic_s_address	[`CORE_NUM(src_x_addr,src_y_addr)]	= SLAVE_WR_PCK_ADDR; 
	ram_data[`CORE_NUM(src_x_addr,src_y_addr)]= {{PORT_NUM_BCD_WIDTH{1'b0}},des_x_addr,des_y_addr,{(32-PORT_NUM_BCD_WIDTH-X_NODE_NUM_WIDTH-Y_NODE_NUM_WIDTH){1'b0}}};	
	ram_addr[`CORE_NUM(src_x_addr,src_y_addr)]=		pck_ptr;
	@ (posedge clk) # 1 ram_we[`CORE_NUM(src_x_addr,src_y_addr)] = 1'b1;
	@ (posedge clk) # 1 ram_we[`CORE_NUM(src_x_addr,src_y_addr)] = 1'b0;
		
	end
endtask

///////////////////////////////////

task automatic recive_pck(
	input [X_NODE_NUM_WIDTH-1	:	0] des_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] des_y_addr,
	input [12						:	0]	pck_size,
	input [18						:	0]	pck_ptr

);
	begin: rcv_pck1
	nic_s_address		[`CORE_NUM(des_x_addr,des_y_addr)]	= SLAVE_RD_PCK_ADDR; 
	
		wait(	nic_s_readdata[`CORE_NUM(des_x_addr,des_y_addr)][`NIC_HAS_PCK_LOC] ); 	
	
		#20		
		nic_s_writedata	[`CORE_NUM(des_x_addr,des_y_addr)]						= {pck_size,pck_ptr}; 
		nic_s_chipselect	[`CORE_NUM(des_x_addr,des_y_addr)]						=	1'b1;
		@ (posedge clk) # 1	nic_s_write[`CORE_NUM(des_x_addr,des_y_addr)]	=	1'b1;
		@ (posedge clk) # 1	nic_s_write[`CORE_NUM(des_x_addr,des_y_addr)]	=	1'b0;
		nic_s_writedata	[`CORE_NUM(des_x_addr,des_y_addr)]						= 	0;
		nic_s_chipselect	[`CORE_NUM(des_x_addr,des_y_addr)]						=	1'b0;
		wait(	nic_s_readdata[`CORE_NUM(des_x_addr,des_y_addr)][`NIC_RD_DONE_LOC] ) ;
		$display ("%d,\t a pck has been stored on core (%d,%d)", $time,des_x_addr,des_y_addr );
		
	end
	
endtask	
	
///////////////////////////////////////


	
task automatic write_prog_hdr (
	input [X_NODE_NUM_WIDTH-1	:	0] src_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] src_y_addr,
	input [X_NODE_NUM_WIDTH-1	:	0] des_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] des_y_addr

);
	begin : hdr2
	nic_s_address	[`CORE_NUM(src_x_addr,src_y_addr)]	= SLAVE_WR_PCK_ADDR; 
	ram_data[`CORE_NUM(src_x_addr,src_y_addr)]= {{PORT_NUM_BCD_WIDTH{1'b0}},des_x_addr,des_y_addr,{(32-PORT_NUM_BCD_WIDTH-X_NODE_NUM_WIDTH-Y_NODE_NUM_WIDTH-1){1'b0}}, 1'b1	};	
	ram_addr[`CORE_NUM(src_x_addr,src_y_addr)]=	0;
	@ (posedge clk) # 1 ram_we[`CORE_NUM(src_x_addr,src_y_addr)] = 1'b1;
	@ (posedge clk) # 1 ram_we[`CORE_NUM(src_x_addr,src_y_addr)] = 1'b0;
		
	end
endtask


///////////////////////////////////////////////

task automatic send_prog_pck(
	input [X_NODE_NUM_WIDTH-1	:	0] src_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] src_y_addr,
	input [X_NODE_NUM_WIDTH-1	:	0] des_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] des_y_addr,
	input [12						:	0]	pck_size,
	input [18						:	0]	pck_ptr


);
	begin: send_pck1
		write_prog_hdr ( src_x_addr,src_y_addr,des_x_addr,des_y_addr);
		#20
		send_pck_cmd (src_x_addr, src_y_addr,	pck_size,pck_ptr);
		wait(	nic_s_readdata[`CORE_NUM(src_x_addr,src_y_addr)][`NIC_WR_DONE_LOC] ) ;
	end
endtask


////////////////////////////////////////////////

task automatic update_cmd_mem (
	input [X_NODE_NUM_WIDTH-1	:	0] des_x_addr,
	input [Y_NODE_NUM_WIDTH-1	:	0] des_y_addr,
	input [31						:	0] jtag_mem_start_addr,
	input [31						:	0] pckt_size,
	input [31						:	0] sdram_start_addr
	);
	begin : update
		@(posedge clk) # 1 cmd_we			=  1'b1;
		cmd_addr = 1;
		cmd_data ={{(32-X_NODE_NUM_WIDTH-Y_NODE_NUM_WIDTH){1'b0}},des_x_addr,des_y_addr}; 
		
		@(posedge clk) # 1 cmd_we			=  1'b1;
		cmd_addr = 2;
		cmd_data = jtag_mem_start_addr;
		
		@(posedge clk) # 1 cmd_we			=  1'b1;
		cmd_addr = 3;
		cmd_data = pckt_size; // transfer size 
	
		@(posedge clk) # 1 cmd_we			=  1'b1;
		cmd_addr= 4;
		cmd_data = sdram_start_addr; //sdram addr
	
		
		@(posedge clk) # 1 cmd_we			=	1'b0;				
		cmd_addr = 0;
	end
endtask

//////////////////////////////////////////////////

task automatic send_cmd (
	input [31			:	0] command
	);
	begin : send_cmdd
		cmd_data		=	command;			
		@(posedge clk) # 1 cmd_we					=  1'b1;
		@(posedge clk) # 1 cmd_we					=	1'b0;			
		wait (cmd_q_b[`JTAG_DONE_LOC] ) ;	
	end
endtask	


/////////////////////////////////////////////////


task automatic write_read_req (
	input [31						:	0] jtag_mem_start_addr,
	input [31						:	0] pckt_size,
	input [31						:	0] sdram_start_addr
	);
	begin : update2
		@(posedge clk) # 1 code_we			=  1'b1;
		code_addr = jtag_mem_start_addr;
		code_data  = sdram_start_addr;
		
		@(posedge clk) # 1 code_we			=  1'b1;
		code_addr = jtag_mem_start_addr+1;
		code_data = pckt_size;
				
		@(posedge clk) # 1 code_we			=	1'b0;				
		code_addr = 0;
		
		//update_cmd_mem (des_x_addr,des_y_addr,jtag_mem_start_addr, pckt_size,sdram_start_addr)
	   update_cmd_mem ( SDRAM_SW_X_ADDR,SDRAM_SW_Y_ADDR,jtag_mem_start_addr,2,0);
		
		
	end
endtask


	

